/**
 * 
 */
package com.aspire.android.heliar.pub.analyzer.mms;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.util.Log;

import com.aspire.android.heliar.Heliar;
import com.aspire.android.heliar.pub.analyzer.PubAnalyzer;
import com.aspire.android.heliar.pub.ContentNode;
import com.aspire.android.heliar.pub.ImageAttachment;
import com.aspire.android.heliar.pub.Pub;
import com.aspire.android.heliar.pub.PubAttachment;
import com.aspire.android.heliar.pub.SoundAttachment;
import com.aspire.android.heliar.raw.Raw;
import com.aspire.android.heliar.raw.mms.MMS;
import com.aspire.android.heliar.raw.mms.MMSImageFrame;

/**
 * @author panglei
 * 
 */
public class StandardMMSAnalyzer implements PubAnalyzer {

	public static final String ANALYZER_NAME = "STANDARD_ANALYZER";

	public static final String SEP_MMS_PARAGRAPH = "\n";

	public static final String PATTERN_MMS_LEVEL1_COLUMN_TITLE = "(【(.*?)】)";
	public static final String PATTERN_MMS_LEVEL2_COLUMN_TITLE = "(\\[(.*?)\\])";
	public static final String PATTERN_MMS_LEVEL3_COLUMN_TITLE_1 = "----------------";
	public static final String PATTERN_MMS_LEVEL3_COLUMN_TITLE_2 = ">>";

	public static final String PATTERN_MMS_ATTACHMENT = "(ATT#<(.*?)>#)";
	public static final String PATTERN_PUB_TITLE = "";

	public static final String FORMAT_MMS_CID = "<%s>";
	public static final String FORMAT_MMS_COLUMN_TITLE = "【%s】";
	public static final String FORMAT_MMS_CHILDREN_COLUMN_TITLE = "[%s]";

	public static final String FILETYPE_JPEG = "jpg";
	public static final String FILETYPE_GIF = "gif";
	public static final String FILETYPE_AMR = "amr";
	public static final String FILETYPE_MIDI = "mid";

	public Pattern attachmentPattern = Pattern.compile(PATTERN_MMS_ATTACHMENT);
	public Pattern columnPattern = Pattern
			.compile(PATTERN_MMS_LEVEL1_COLUMN_TITLE);
	public Pattern childColumnPattern = Pattern
			.compile(PATTERN_MMS_LEVEL2_COLUMN_TITLE);

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.aspire.android.heliar.pub2.analyzer.PubAnalyzer#analyse(com.aspire
	 * .android.heliar.raw.Raw)
	 */
	@Override
	public Pub analyse(Raw raw) {

		Pub pub = new Pub();
		MMS mms = (MMS) raw;

		Log.d(Heliar.LOG_TAG, mms.getSubject() + " address:" + mms.getAddress());

		pub.setRawId(String.valueOf(mms.getId()));
		pub.setTitle(mms.getSubject());
		pub.setAuthor(mms.getAddress());
		pub.setDate(mms.getDate());
		pub.setRawFullContent(mms.getFullContent());

		extract(pub, mms);

		return pub;
	}

	private void extract(Pub pub, MMS mms) {
		String[] lines = pub.getRawFullContent().split(SEP_MMS_PARAGRAPH);

		int lineNumber = 0;
		ContentNode rootNode = pub.getRootNode();
		ContentNode currentNode = pub.getRootNode();

		boolean findCover = false;
		boolean findDesc = false;
		for (String line : lines) {

			if (line.contains(PATTERN_MMS_LEVEL3_COLUMN_TITLE_1)) {
				lineNumber++;
				continue;
			}

			String level1 = findString(line, columnPattern);
			if (level1 != null) {
				// find level1 node
				ContentNode node = new ContentNode();
				node.setTitle(level1);
				node.setParentNode(rootNode);
				rootNode.addChildNode(node);
				// Change current node
				currentNode = node;

				// check node content
				String rawNodeTitle = String.format(FORMAT_MMS_COLUMN_TITLE,
						level1);
				if ((line.length() - 1) > rawNodeTitle.length()) {
					String content = line.replaceAll(rawNodeTitle, "");
					currentNode.setContent(content);

					if (!findDesc) {
						pub.setDesc(content);
						findDesc = true;
					}
				}

				lineNumber++;
				continue;
			}

			String level2 = findString(line, childColumnPattern);
			if (level2 != null) {
				// find level2 node
				ContentNode node = new ContentNode();
				node.setTitle(level2);
				node.setParentNode(currentNode);
				// Change current node
				currentNode.addChildNode(node);
				currentNode = node;
				lineNumber++;
				continue;
			}

			int nextLineNumber = ((lineNumber + 1) >= lines.length) ? lines.length - 1
					: (lineNumber + 1);
			if (lines[nextLineNumber]
					.contains(PATTERN_MMS_LEVEL3_COLUMN_TITLE_1)
					|| line.startsWith(PATTERN_MMS_LEVEL3_COLUMN_TITLE_2)) {
				ContentNode node = new ContentNode();
				node.setTitle(line);
				// switch currentNode
				if (currentNode.getParentNode() != null) {
					currentNode = currentNode.getParentNode();
				}
				currentNode.setParentNode(currentNode);
				currentNode.addChildNode(node);
				// set current node
				currentNode = node;

				lineNumber++;
				continue;
			}

			String cid = findString(line, attachmentPattern);
			if (cid != null) {
				// find new attchment to add current node
				PubAttachment pubAttachment = createPubAttachment(cid, mms);
				// TODO Check attachment's cid without subfix
				if (pubAttachment != null) {
					// Set Pub cover
					if ((pubAttachment instanceof ImageAttachment)
							&& !findCover) {
						pub.setCover((ImageAttachment) pubAttachment);
						findCover = true;
					}

					currentNode.addAttachment(pubAttachment);

					lineNumber++;
					continue;
				}
			}

			if (currentNode.getContent() != null) {
				currentNode.setContent(currentNode.getContent()
						+ SEP_MMS_PARAGRAPH + line);
			} else {
				currentNode.setContent(line);
			}

			lineNumber++;
		}
	}

	public PubAttachment createPubAttachment(String cid, MMS mms) {
		PubAttachment attachment = null;

		Log.d(Heliar.LOG_TAG, "cid = " + cid);

		if (cid.endsWith(FILETYPE_AMR)) {
			attachment = new SoundAttachment();
			attachment.setContentType(PubAttachment.CONTENT_TYPE_SOUND_AMR);
		}

		if (cid.endsWith(FILETYPE_MIDI)) {
			attachment = new SoundAttachment();
			attachment.setContentType(PubAttachment.CONTENT_TYPE_SOUND_MIDI);
		}

		if (cid.endsWith(FILETYPE_JPEG)) {
			attachment = new ImageAttachment();
			attachment.setContentType(PubAttachment.CONTENT_TYPE_IMAGE_JPEG);

			MMSImageFrame imageFrame = (MMSImageFrame) mms
					.getAttachmentFrameMap().get(
							String.format(FORMAT_MMS_CID, cid));
			((ImageAttachment) attachment).setBitmap(imageFrame.getImage());
		}

		if (cid.endsWith(FILETYPE_GIF)) {
			attachment = new ImageAttachment();
			attachment.setContentType(PubAttachment.CONTENT_TYPE_IMAGE_GIF);

			MMSImageFrame imageFrame = (MMSImageFrame) mms
					.getAttachmentFrameMap().get(
							String.format(FORMAT_MMS_CID, cid));
			((ImageAttachment) attachment).setBitmap(imageFrame.getImage());
		}

		if (attachment != null) {
			attachment.setName(cid);
		}
		return attachment;
	}

	public String findString(String line, Pattern pattern) {

		Matcher matcher = pattern.matcher(line);
		boolean matchFound = matcher.find();
		String attachement = null;
		if (matchFound) {
			attachement = matcher.group(2);
		}

		return attachement;
	}

}
